package net.sample.gismeteo.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Observable;
import java.util.Observer;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;

import android.util.Log;

/**
 * The HTTP client for weather forecast retrieving. 
 * @author vkozlov
 * @version $Id: $
 */
public class WeatherRetrievalHttpClient extends Observable implements Runnable {

	private static final String TAG = "WeatherRetrievalHttpClient";

	private static final String WEATHER_URL = "http://informer.gismeteo.ru/xml/33815_1.xml";
	private static final int SLEEP_INTERVAL = 60000;

	private Thread workerthread;
	private boolean doStop = false;

	/**
	 * Constructor.
	 * @param observer the observer for this service.
	 */
	public WeatherRetrievalHttpClient(Observer observer) {
		super();
		this.addObserver(observer);
		Log.e(TAG, "Observable instance created and bound to observer.");
	}

	/**
	 * Retrieves weather forecast data using HTTP protocol.
	 * @return XML-string with weather forecast
	 */
	private String getWeatherXML() {
		Log.d(TAG, "Performing weather request...");

		HttpUriRequest request = null;
        HttpResponse resp = null;
        InputStream is = null;

		DefaultHttpClient httpClient = new DefaultHttpClient();

		request = new HttpGet(WEATHER_URL);
		try {
			resp = httpClient.execute(request);
			HttpEntity entity = resp.getEntity();
			is = entity.getContent();
			String result = convertStreamToString(is);
			is.close();
			Log.d(TAG, "Weather request done.");
			return result;
		} catch (ClientProtocolException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}
		return null;
	}

	/**
	 * Start the service worker thread. 
	 */
	public void start() {
		workerthread = new Thread(this);
		workerthread.start();
	}

	/**
	 * Signal service worker thread to stop. 
	 */
	public void stop() {
		doStop = true;
	}

	/**
	 * Main loop of a service.
	 */
	public void run() {
		while (!doStop) {
			String lDataXML = getWeatherXML();
			if (lDataXML != null) {
				setChanged();
				notifyObservers(lDataXML);
			}
			try {
				Thread.sleep(SLEEP_INTERVAL);
			} catch (InterruptedException e) {
				Log.e(TAG, e.getMessage());
			}
		}
	}

	/**
	 * Converts content of given input stream to a string.
	 * @param is the input stream
	 * @return string with data readed frin stream.
	 */
	private static String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means
         * there's no more data to read. Each line will appended to a StringBuilder
         * and returned as String.
         */
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }


}
